#include "PlayOnBehaviour.h"

//rozhodovanie sa pocas modu playon
void PlayOnBehaviour::Behave()
{
#ifndef GOALIE
	PlayerRunPlayOn();
#endif

#ifdef GOALIE
	GetPlayGoalieBehaviour()->Behave();
	GoalieSetView();
	return;
#else

//	if(GetPlayerRole() == PR_Goalie)
//		DBGN("%d: BallAge: %d, valid: %s", world->state->GetSimTime(), world->ball->GetAge(), world->ball->IsValid() ? "true" : "false");
	if(world->ball->IsValid() || (DATA_STORAGE.playerRole == PR_Goalie && world->ball->GetAge() < 11))
	{
		if(DATA_STORAGE.IsBallKickable())
		{
			GetWithBallBehaviour()->Behave();
		}
		else
		{
			GetWithoutBallBehaviour()->Behave();
		}

		// Poslem spravu svojim spoluhracom
		GetSayBehaviour()->Behave();
		

//		if((!world->ball->IsValid() || world->ball->GetAge() > 3) && (world->ball->pos - world->me->pos).GetLength() > 4)

		ViewWidth odporucana_sirka = WidthFromDistance(DATA_STORAGE.ballDistance);
		if(DATA_STORAGE.playerRole == PR_Goalie && DATA_STORAGE.GetNextSynchMode() == Synch_WaitForVI)
		{
			commandGenerator->ChangeView(WIDE_VIEW);
		}
		else if(odporucana_sirka != world->me->GetViewWidth())
		{
			switch(odporucana_sirka)
			{
			case WIDE_VIEW:
				commandGenerator->ChangeView(WIDE_VIEW);
				DATA_STORAGE.SetNextSynchMode(Synch_Normal);
				break;
			case NORMAL_VIEW:
				GetTurnNeckToBehaviour()->NeckSynchronizationWithVI(NOR_VIEW);
				DATA_STORAGE.SetNextSynchMode(Synch_Normal);
				break;
			case NARROW_VIEW:
				GetTurnNeckToBehaviour()->NeckSynchronizationWithVI(NAR_VIEW);
				DATA_STORAGE.SetNextSynchMode(Synch_VIOnly);
				break;
			}	
		}
	}
	// Nemame informaciu o lopte
	else 
	{
		GetSearchForBallBehaviour()->Behave();
	}
#endif //GOALIE
}

void PlayOnBehaviour::PlayerRunPlayOn()
{
	// Ak nikoho nepocuvam a nie som veduci a viem kto je veduci, tak si nastavim nanho AttentionTo
	if (!DATA_STORAGE.leadership.attentionToSet && !DATA_STORAGE.leadership.amILeader)
	{
		if (DATA_STORAGE.leadership.leaderUniform > 0)
		{
			commandGenerator->AttentionTo(DATA_STORAGE.leadership.leaderUniform);
			DATA_STORAGE.leadership.attentionToSet = true;
		}
	}

	if (DATA_STORAGE.leadership.amILeader)
	{
		int simTime = world->state->GetSimTime();

		if (simTime > (DATA_STORAGE.leadership.lastChangeTime + 1) && //rezerva 1 cyklus, aby sa vsetci dozvedeli o zmene
			(simTime - DATA_STORAGE.leadership.lastSendTime) > 4) //od pokusu o zmenu veduceho ubehli najviac tri cykly
		{
			if (simTime % 59 == 0)
			{
				if (DATA_STORAGE.GetNearestFriendDistance(world->me->pos) >= 40)
				{
					fprintf(stderr, "[LPT] u%d t%d: Som prilis sam. Nejdem sa vzdat vedenia.\n", world->me->GetUniform(), simTime);
					//sabor RunToPoint(world->friends[GetNearestFriend(world->me->pos)].pos, true);
				} 
				else
				{
					GetLeadershipBehaviour()->SendTySiLeaderMSG(world->friends[DATA_STORAGE.GetNearestFriend(world->me->pos)].GetUniform());
					DATA_STORAGE.leadership.lastChangeTime = simTime;
				}
			} 
			else if (simTime % 17 == 0)
			{
				//sabor if (DATA_STORAGE.GetNearestFriendDistance(world->me->pos) >= 50)
				//sabor   RunToPoint(world->friends[GetNearestFriend(world->me->pos)].pos,true);
				//cyklicka zmena formacie
				if (DATA_STORAGE.leadership.currentFormation == LPT_FR_LAST)
					DATA_STORAGE.leadership.currentFormation = LPT_FR_FIRST; else
					DATA_STORAGE.leadership.currentFormation = (LPT_FormationType) ((int) DATA_STORAGE.leadership.currentFormation + 1);
				DATA_STORAGE.leadership.casZmenyFormacie = simTime;
				GetLeadershipBehaviour()->SendZmenaFormacieLeaderMSG();
				DATA_STORAGE.leadership.lastChangeTime = simTime;
			}
		}
	}
}

//nastavenie pohladu brankara
void PlayOnBehaviour::GoalieSetView()
{
	if((world->ball->GetAge() > 3) && ((world->ball->pos - world->me->pos).GetLength() > 4))
	{
		commandGenerator->ChangeView(WIDE_VIEW);
		DATA_STORAGE.SetNextSynchMode(Synch_Normal);
	}
	else
	{
		ViewWidth odporucana_sirka = WidthFromDistance(DATA_STORAGE.ballDistance);
		if(DATA_STORAGE.playerRole == PR_Goalie && DATA_STORAGE.GetNextSynchMode() == Synch_WaitForVI)
		{
			commandGenerator->ChangeView(WIDE_VIEW);
		}
		else if(odporucana_sirka != world->me->GetViewWidth())
		{
			switch(odporucana_sirka)
			{
			case WIDE_VIEW:
				commandGenerator->ChangeView(WIDE_VIEW);
				DATA_STORAGE.SetNextSynchMode(Synch_Normal);
				break;
			case NORMAL_VIEW:
				GetTurnNeckToBehaviour()->NeckSynchronizationWithVI(NOR_VIEW);
				DATA_STORAGE.SetNextSynchMode(Synch_Normal);
				break;
			case NARROW_VIEW:
				GetTurnNeckToBehaviour()->NeckSynchronizationWithVI(NAR_VIEW);
				DATA_STORAGE.SetNextSynchMode(Synch_VIOnly);
				break;
			}	
		}
	}
}

// Vrati pozorovaci uhol v zavislosti na vzdialenosti
ViewWidth PlayOnBehaviour::WidthFromDistance(float distance)
{
	if(DATA_STORAGE.playerRole == PR_Goalie)
	{
		if(distance < 20)
			return NARROW_VIEW;
		if(distance > 50.0f)
			return WIDE_VIEW;
		else
			return NORMAL_VIEW;
	}
	else 
	{	
		// @JW

		PlayMode pm = world->state->GetPlayMode();

	#ifndef GOALIE 
		
		if((pm == PM_FreeKick_Our || pm == PM_IndFreeKick_Our || pm == PM_KickIn_Our || pm == PM_CornerKick_Our) &&
			(distance < 1.0f))
		{
			return NORMAL_VIEW;
		}
	#else

		if((pm == PM_FreeKick_Our || pm == PM_GoalKick_Our || pm == PM_IndFreeKick_Our || pm == PM_KickIn_Our || pm == PM_CornerKick_Our) &&
			(distance < 1.0f))
		{
			return WIDE_VIEW;
		}
	#endif		
		// @JW
		else if(distance < 15.0f) // Default 5.f)			// (0.75f * world->params->server->visible_distance)
		{
			return NARROW_VIEW;
		}
		else if(distance > 30.0f) // Default 20.0f)
		{
			return WIDE_VIEW;
		}
		else
		{
			return NORMAL_VIEW;
		}
	}
}
